package depots

// 小爱技能开放平台请求开发者的接口定义
type XiaoAi struct {
	Version string         `json:"version"` // 版本号，当前为1.0
	Query   string         `json:"query"`   // 用户语音输入的识别结果
	Session XiaoAi_Session `json:"session"` // 一轮对话相关的信息
	Context XiaoAi_Context `json:"context"` // 上下文相关的信息
	Request XiaoAi_Request `json:"request"` // 请求相关的信息
}

type XiaoAi_Session struct {
	SessionId   string                 `json:"session_id"`  // 唯一标识一轮session
	Application *XiaoAi_Application    `json:"application"` // 当前的技能信息
	Attributes  map[string]interface{} `json:"attributes"`  // 可存储需要持久化的数据，每次请求都会带上
	User        *XiaoAi_User           `json:"user"`        // 用户相关信息
}

type XiaoAi_Application struct {
	AppId string `json:"app_id"` // 技能id
}

type XiaoAi_User struct {
	UserId      string `json:"user_id"`       // 用户唯一id，默认会对用户id进行加密，所以这个id不是真实的小米id，但是可以作为唯一标识
	AccessToken string `json:"access_token"`  // 如果使用了OAuth进行账号绑定，这里存放用户绑定后获取的token
	IsUserLogin bool   `json:"is_user_login"` // 使用是否在设备上登录了小米账号
	Gender      string `json:"gender"`        // 声纹识别出来的性别, 目前支持三种类型: male, female, child
}

type XiaoAi_Context struct {
	DeviceId string                 `json:"device_id"` // 设备唯一标识
	Passport string                 `json:"passport"`  // OAuth账号绑定的额外信息
	AppInfo  []XiaoAi_ClientAppInfo `json:"app_info"`  // 客户端APP相关信息
}

type XiaoAi_ClientAppInfo struct {
	PkgName     string `json:"pkg_name"`     // 包名
	VersionName string `json:"version_name"` // 版本号
}

type XiaoAi_Request struct {
	Type          int64           `json:"type"`           // 请求的类型，分别标识，0：技能进入请求； 1：技能进行中请求;2：请求结束请求
	RequestId     string          `json:"request_id"`     // 请求的唯一标识
	Timestamp     int64           `json:"timestamp"`      // 时间戳
	NoResponse    bool            `json:"no_response"`    // 是否用户没响应小爱（例如用户没有在小爱音箱旁边）
	EventType     string          `json:"event_type"`     // 事件类型（详见事件）
	EventProperty string          `json:"event_property"` // 事件的相关信息
	Locale        string          `json:"Locale"`         // 本地化设置
	SlotInfo      XiaoAi_SlotInfo `json:"slot_info"`      // 意图信息（详见意图）
}

type XiaoAi_EventProperty struct {
	AsrText   string `json:"asr_text"`    // 录音的语音识别结果文本
	MsgFileId string `json:"msg_file_id"` // 录音所得的文件id
}

type XiaoAi_SlotInfo struct {
	IntentName  string         `json:"intent_name"`  // 此次请求命中的意图名称
	IsConfirmed bool           `json:"is_confirmed"` // 此命中的意图是否确认了，所谓意图确认是指上一轮命中了这个意图，假如开发者配置了意图确认，平台会要求用户确认一次，假如这次用户确认了，会将这个bool值设置为true
	Slots       []XiaoAi_Slots `json:"slots"`        // 该意图提取出的所有槽位值
}

type XiaoAi_Slots struct {
	Name            string `json:"name"`              // 槽位名称
	Value           string `json:"value"`             // 提取出的槽位值，例如city槽位可能提取的值是北京
	IsInquireFailed bool   `json:"is_inquire_failed"` // 追问超过开发者设置的次数会通过这个值告诉开发者
}

// 开发者返回给小爱技能开放平台的接口定义
type XiaoAi_Return struct {
	Version           string                 `json:"version"`            // 返回的协议版本，默认请用1.0
	SessionAttributes map[string]interface{} `json:"session_attributes"` // 期望小爱技能平台帮忙持久化的jsobject
	IsSessionEnd      bool                   `json:"is_session_end"`     // 是否结束当前会话
	Response          XiaoAi_Respone         `json:"response"`           // 返回的具体信息
}

type XiaoAi_Respone struct {
	ToSpeak        *XiaoAi_ToSpeak         `json:"to_speak"`        // tts要说的话，通常简单的回复可以使用这个字段
	ToDisplay      *XiaoAi_ToDisplay       `json:"to_display"`      // 有屏设备显示的数据
	Directives     []*XiaoAi_Directive     `json:"directives"`      // 设备的复杂操作通常放在这里，例如多句tts，url音频播放等
	OpenMic        bool                    `json:"open_mic"`        // 是否需要开麦（相关指导建议详见最佳实践），默认不开麦
	NotUnderstand  bool                    `json:"not_understand"`  // 是否理解用户的请求，具体作用详见最佳实践
	Action         interface{}             `json:"action"`          // 动作类型, 常见的动作有：leave_msg, play_msg等
	ActionProperty *XiaoAi_ActionProperty  `json:"action_property"` // 动作属性
	RegisterEvents []*XiaoAi_RegisterEvent `json:"register_events"` // 需要注册的事件类型
}

type XiaoAi_ToSpeak struct {
	Type int64  `json:"type"` // tts的类型，目前仅支持0：TTS
	Text string `json:"text"` // tts要说的文本
}

type XiaoAi_ToDisplay struct {
	Type       int64              `json:"type"`        // 显示类型，目前支持0：文字，1：html，2：native ui，3：widgets，目前主要用在电视和手机等有屏设备
	Text       string             `json:"text"`        // 显示的文字
	Url        interface{}        `json:"url"`         // 假如显示html则通过这个链接指定
	UiTemplate *XiaoAi_UiTemplate `json:"ui_template"` // 显示的模板，有屏设备支持一些显示模板，可以通过这个配置
}

type XiaoAi_Directive struct {
	Type      string           `json:"type"`       // 动作的类型，audio播放音频，tts播放文字
	AudioItem XiaoAi_AudioItem `json:"audio_item"` // 音频内容
	TTSItem   XiaoAi_TTSItem   `json:"tts_item"`   // tts内容
}

type XiaoAi_AudioItem struct {
	Stream XiaoAi_AudioStream `json:"stream"` // 音频流
}

type XiaoAi_AudioStream struct {
	Token                string `json:"token"`                  // 	播放资源鉴权用的token
	Url                  string `json:"ur"`                     // 	播放地址
	OffsetInMilliseconds int64  `json:"offset_in_milliseconds"` // 偏移地址	播放地址
}

type XiaoAi_TTSItem struct {
	Type string `json:"type"` // tts的类型，目前仅支持text：普通文本
	Text string `json:"text"` // 文本内容
}

type XiaoAi_ActionProperty struct {
	FileIdList []string `json:"file_id_list"` // 要播放的文件id，用于play_msg动作
}

type XiaoAi_RegisterEvent struct {
	EventName string `json:"event_name"` // 事件名称，目前仅支持：mediaplayer.playbacknearlyfinished
}

type XiaoAi_UiTemplate struct {
	Type  int64         `json:"type"`  // 使用的模板的类型，0：list view，1：single image view，2：double image view
	Items []XiaoAi_Item `json:"items"` // Ui template type为0时必填
	Logo  string        `json:"logo"`  // 开发者的logo地址
	Item  XiaoAi_Item   `json:"item"`  // Ui template的type为1,2时必填
}

type XiaoAi_Item struct {
	ImageStyle      string                 `json:"image_style"`      // 图片的样式
	Images          []string               `json:"images"`           // 图片列表
	Intent          string                 `json:"Intent"`           // 响应点击事件
	Title           string                 `json:"title"`            // 标题
	Body            map[string]interface{} `json:"body"`             // 主题内容
	BackgroundImage string                 `json:"background_image"` // 背景图片
}

// 获取slot
func (intent *XiaoAi) GetSlot(slotName string) *XiaoAi_Slots {
	for _, v := range intent.Request.SlotInfo.Slots {
		if v.Name == slotName {
			return &v
		}
	}
	return nil
}

// 回答
func (intent *XiaoAi) Answer(text string) *XiaoAi_Return {
	return &XiaoAi_Return{
		Version:      "1.0",
		IsSessionEnd: false,
		Response: XiaoAi_Respone{
			ToSpeak: &XiaoAi_ToSpeak{
				Type: 0,
				Text: text,
			},
			ToDisplay: &XiaoAi_ToDisplay{
				Type: 0,
				Text: text,
			},
		},
	}
}

// 获取session内容
func (intent *XiaoAi) GetSessionAttribute(key string) interface{} {
	if value, ok := intent.Session.Attributes[key]; ok {
		return value
	}
	return nil
}

// 开麦
func (m *XiaoAi_Return) OpenMic(b bool) *XiaoAi_Return {
	m.Response.OpenMic = b
	return m
}

// 是否结束会话
func (m *XiaoAi_Return) IsEnd(b bool) *XiaoAi_Return {
	m.IsSessionEnd = b
	return m
}

// 是否理解意图
func (m *XiaoAi_Return) NotUnderstand(b bool) *XiaoAi_Return {
	m.Response.NotUnderstand = b
	return m
}

// 添加session_attributes
func (m *XiaoAi_Return) AddSessionAttribute(key string, value interface{}) *XiaoAi_Return {
	if len(m.SessionAttributes) == 0 {
		m.SessionAttributes = make(map[string]interface{})
	}
	m.SessionAttributes[key] = value
	return m
}
